/**
The MIT License (MIT) * Copyright (c) 2015 铭飞科技

 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:

 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.

 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package com.mingsoft.cms.action.web;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mingsoft.base.action.BaseAction;
import com.mingsoft.basic.biz.IAppBiz;
import com.mingsoft.basic.biz.ICategoryBiz;
import com.mingsoft.basic.biz.IModelBiz;
import com.mingsoft.base.constant.ModelCode;
import com.mingsoft.basic.entity.AppEntity;
import com.mingsoft.cms.biz.IArticleBiz;
import com.mingsoft.cms.biz.IColumnBiz;
import com.mingsoft.basic.biz.IContentModelBiz;
import com.mingsoft.basic.biz.IFieldBiz;
import com.mingsoft.cms.biz.ISearchBiz;
import com.mingsoft.cms.entity.ColumnEntity;
import com.mingsoft.basic.entity.ContentModelEntity;
import com.mingsoft.basic.entity.FieldEntity;
import com.mingsoft.cms.entity.SearchEntity;
import com.mingsoft.cms.parser.CmsParser;
import com.mingsoft.parser.IParserRegexConstant;
import com.mingsoft.parser.impl.general.ListParser;
import com.mingsoft.util.FileUtil;
import com.mingsoft.util.PageUtil;
import com.mingsoft.util.StringUtil;

/**
 * 
 * 
 * 
 * 
 * <p>
 * <b>铭飞科技</b>
 * </p>
 * 
 * <p>
 * Copyright: Copyright (c) 2014 - 2015
 * </p>
 * 
 * @author killfen
 * 
 * <p>
 * Comments: 搜索，根据搜索结果生成html页面
 * </p>
 * 
 * <p>
 * Create Date:2015-4-21
 * </p>
 * 
 * <p>
 * Modification history:
 * </p>
 */
@Controller(value = "webSearchAction")
@RequestMapping("/html")
public class SearchAction extends BaseAction {

	/**
	 * 注入文章业务层
	 */
	@Autowired
	private IArticleBiz articleBiz;
	
	

	/**
	 * 内容模型业务层
	 */
	@Autowired
	private IContentModelBiz contentModelBiz;
	

	/**
	 * 内容字段业务层
	 */
	@Autowired
	private IFieldBiz fieldBiz;

	/**
	 * 注入站点业务层
	 */
	@Autowired
	private IAppBiz appBiz;

	/**
	 * 注入搜索业务层
	 */
	@Autowired
	private ISearchBiz searchBiz;

	/**
	 * 注入栏目业务层
	 */
	@Autowired
	private IColumnBiz columnBiz;
	
	/**
	 * 注入分类业务层
	 */
	@Autowired
	private ICategoryBiz categoryBiz;
	
	/**
	 * 文章解析器
	 */
	@Autowired
	private CmsParser cmsParser;
	
	/**
	 * 模块管理biz
	 */
	@Autowired
	private IModelBiz modelBiz;
	
	/**
	 * 手机端模板前缀
	 */
	public static final String MOBILE = "m";
	
	/**
	 * 实现前端页面的文章搜索
	 * @param request
	 * @param websiteId 应用id
	 * @param searchId 搜索id
	 * @param response 
	 */
	@RequestMapping(value = "/{websiteId}/{searchId}/search")
	@ResponseBody
	public void search(HttpServletRequest request, @PathVariable int websiteId, @PathVariable int searchId, HttpServletResponse response) {
		
		
		Map<String, String> articleField = getMapByProperties("com/mingsoft/cms/resources/article_field");
		Map<String, String[]> field = new HashMap<String, String[]>();
		AppEntity app = (AppEntity) appBiz.getEntity(websiteId);
		// 获取模版名称
		String tmpName = app.getAppStyle();
		// 获取系统模版存放物理路径
		String tmpPath = getRealPath(request, IParserRegexConstant.REGEX_SAVE_TEMPLATE);
		//排序参数格式 字段名称-方式
		String sort = request.getParameter("sort");
		Map<String,String> sortMap = null;
		if(!StringUtil.isBlank(sort) && sort.indexOf("-")>0) {
			sortMap = new HashMap();
			String[] tmp = sort.split("-");
			sortMap.put("order",tmp[0]);
			sortMap.put("by",tmp[1]);
		}
		if (websiteId != app.getAppId()) {
			this.outString(response, this.getResString("err"));
			return;
		}
		field = request.getParameterMap(); // 读取请求字段
		//获取当前页码
		Integer pageNo = this.getInt(request, "pageNo",1);
		// 获取栏目ID
		String basicCategoryId = request.getParameter("categoryId");
		Integer [] categoryIds = null;
		if (basicCategoryId!=null ) {
			if (StringUtil.isIntegers(basicCategoryId.split(","))) {
				categoryIds = StringUtil.stringsToIntegers( basicCategoryId.split(","));
				basicCategoryId = categoryIds[0]+"";
			}
		}
		ColumnEntity column = null; //当前栏目
		ContentModelEntity contentModel = null; //栏目对应模型
		List fieldList = null; //栏目对应字段
		// 若栏目ID不为空，则选择了栏目
		if (StringUtil.isInteger(basicCategoryId)) {
			column = (ColumnEntity) columnBiz.getEntity(Integer.valueOf(basicCategoryId));
			// 获取表单类型的id
			if (column != null) {
				contentModel = (ContentModelEntity) contentModelBiz.getEntity(column.getColumnContentModelId());
				if(contentModel!=null){
					fieldList = fieldBiz.queryByContentModelId(contentModel.getCmId());
				}
			}
		}
		SearchEntity search = (SearchEntity) searchBiz.getByIdAndAppId(searchId,app.getAppId()); //获取对应搜索模型
		// 默认显示的数量为20条
		int size = 1;
		if (search != null) {
			String webSiteTmpPath = "";
			if (isMobileDevice(request) && !StringUtil.isBlank(app.getAppMobileStyle())) {
				// 根据站点id组装站点信息路径　格式：templets／站点ID/模版风格
				webSiteTmpPath = tmpPath + File.separator + app.getAppId() +File.separator+ tmpName + File.separator +app.getAppMobileStyle();
			} else {
				webSiteTmpPath = tmpPath + File.separator + app.getAppId() + File.separator + tmpName;
			}
			// 读取模板内容
			String htmlContent = FileUtil.readFile(webSiteTmpPath + File.separator + search.getSearchTemplets());
			// 文章字段集合
			Map<String, Object> articleFieldName =  new HashMap<String, Object>();
			// 自定义字段集合
			Map<String, String> diyFieldName = new HashMap<String, String>();
			// 分页连接地址
			String pageUrl = app.getAppHostUrl() + File.separator + "html" + File.separator + websiteId + File.separator + searchId + File.separator + "search.do";
			// 遍历取字段集合
			for (Entry<String, String[]> entry : field.entrySet()) {
				if (entry != null) {
					String value = entry.getValue()[0]; // 处理由get方法请求中文乱码问题
					if (StringUtil.isBlank(value)) {
						continue;
					}
					if (request.getMethod().equals(RequestMethod.GET)) { // 如果是get方法需要将请求地址参数转吗
						value = StringUtil.isoToUTF8(value);
					}
					// 若为文章字段，则保存至文章字段集合；否则保存至自定义字段集合
					if (!StringUtil.isBlank(articleField.get(entry.getKey())) && !StringUtil.isBlank(value)) {
						articleFieldName.put(entry.getKey(), value);
					}else {
						if (!StringUtil.isBlank(value)) {
							diyFieldName.put(entry.getKey(), value);
						}
						
					}
					htmlContent = htmlContent.replaceAll("\\{ms:search." + entry.getKey() + "/\\}", value); // 将用户请求的值返回到页面上；
					
				}
			}

			
			Integer modelId = modelBiz.getEntityByModelCode(ModelCode.CMS_COLUMN).getModelId(); // 查询当前模块编号
			diyFieldName.put("pageNo", null);
			//组织链接地址
			pageUrl = StringUtil.buildUrl(pageUrl, articleFieldName);
			pageUrl = StringUtil.buildUrl(pageUrl, diyFieldName);
			
			//保存栏目Id
			List ids  = null;
			if (StringUtil.isInteger(basicCategoryId)) {
				ids  = categoryBiz.queryChildrenCategory(Integer.parseInt(basicCategoryId),this.getAppId(request),modelId);
				if (categoryIds!=null && categoryIds.length>0) {
					for(Integer id:categoryIds) {
						ids.addAll(categoryBiz.queryChildrenCategory(id,this.getAppId(request),modelId));
					}
				}			
			}
			Map whereMap  = this.searchMap(articleFieldName, diyFieldName, fieldList);
			// 获取符合条件的文章总数
			int count = articleBiz.getSearchCount(contentModel,whereMap, websiteId,ids);
			List articleList = new ArrayList();
			// 读取列表标签中中的
			Map<String, String> property = ListParser.listProperty(htmlContent, true);
			// 列表每页显示的数量
			if (StringUtil.string2Int(property.get(ListParser.LIST_SIZE)) > 0) {
				size = StringUtil.string2Int(property.get(ListParser.LIST_SIZE));
			}
			// 页面对象
			PageUtil page = new PageUtil(pageNo, size, count, pageUrl);
			// 判断列表标签中是否存在
			String isPaging = property.get(ListParser.LIST_ISPAGING);
			// 判断是否存在分页,不存在则分页对象不存在
			if (isPaging == null || !isPaging.equals("true")) {
				page = null;
			} 
			articleList = articleBiz.queryListForSearch(contentModel, whereMap, page, websiteId,ids,sortMap);
			Map map  = new HashMap();
			map.put(CmsParser.CUR_PAGE_NO, pageNo);
			map.put(CmsParser.SEARCH_LIST_ARTICLE, articleList);
			//移动端与pc端分离
			if (isMobileDevice(request) && !StringUtil.isBlank(app.getAppMobileStyle())) {
				// 对模板内容进行解析
				map.put(CmsParser.MOBILE,this.MOBILE);
				// 对模板内容进行解析
				htmlContent = cmsParser.parse(htmlContent,app,column,articleList,page,map);//generaterFactory.buildSearch(app, htmlContent, webSiteTmpPath, no, articleList,null, column, page,app.getAppMobileStyle());				
			} else {
				// 对模板内容进行解析
				htmlContent = cmsParser.parse(htmlContent,app,column,articleList,page,map);// generaterFactory.buildSearch(app, htmlContent, webSiteTmpPath, no, articleList, null,column, page);				
			}
			this.outString(response, htmlContent);
		} else {
			this.outString(response, this.getResString("err"));
		}
	}
	
	
	
	

	
/**
 * 动态组织查询where条件
 *  获取查询条件的Map key:字段名 value:List 字段的各种判断值 list[0]:是否为自定义字段 list[1]:是否为整形
	 * list[2]:是否是等值查询 list[3]:字段的值
 * @param articleField 文章字段
 * @param diyFieldName 动态字段
 * @param fields 模型对应的字段类型
 * @return 
 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Map<String, List> searchMap(Map<String, Object> articleField, Map<String, String> diyFieldName, List fields) {
		Map<String, List> map = new HashMap<String, List>();
		
		// 遍历文章中的字段
		for (Iterator iter = articleField.keySet().iterator(); iter.hasNext();) {
			String key = iter.next().toString();
			String fieldValue = articleField.get(key).toString();
			List list = new ArrayList();
			List listValue = new ArrayList();
			// 是否为自定义字段
			list.add(false);
			
			// 是否是数字类型，true:不是
			list.add(true);
			// 是否是模糊查询3
			list.add(true);
			// 字段值
			listValue.add(articleField.get(key));
			list.add(listValue);
			map.put(key, list);
		}
		
		// 遍历字段自定义字段
		for (Iterator iter = diyFieldName.keySet().iterator(); iter.hasNext();) {
			String key = iter.next().toString();
			String fieldValue = diyFieldName.get(key);
			// 获取字段实体
			FieldEntity field = this.get(key, fields);
			if (field != null) {
				List list = new ArrayList();
				// 是否为自定义字段0
				list.add(0, true);
				List listValue = new ArrayList();
				// 字段的值
				if (field.getFieldType() == IFieldBiz.INT || field.getFieldType() == IFieldBiz.FLOAT) {
					// 判断是否为区间查询

					if (diyFieldName.get(key).toString().indexOf("-") > 0) {
						String[] values = fieldValue.toString().split("-");
						// 是否是数字类型，false:是
						list.add(false);
						// 是否是区间比较 false:是
						list.add(false);
						// 字段值1
						listValue.add(values[0]);
						listValue.add(values[1]);
					} else {
						// 是否是数字类型，false:是2
						list.add(false);
						// 是否是区间比较 true:不是3
						list.add(true);
						// 字段值 1
						listValue.add(fieldValue);
					}
				} else {
					// 是否是数字类型，true:不是2
					list.add(true);
					list.add(false);
					// 字段值 1
					listValue.add(fieldValue);
				}
				list.add(listValue);
				map.put(key, list);
			}
		}
		return map;
	}

	/**
	 *  根据字段名称获取字段类型
	 * @param columnName 字段名称
	 * @return 字段实体
	 */
	private FieldEntity get(String columnName,List<FieldEntity> fields) {
		if (fields==null) {
			return null;
		}
		for(FieldEntity field:fields) {
			if (field.getFieldFieldName().equals(columnName)) {
				return field;
			}
		}
		return null;
	}
	
}